home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 2: Applications / Linux Cubed Series 2 - Applications.iso / math / yplot-0.000 / yplot-0 / yplot-0.9 / ljiip.c < prev    next >
C/C++ Source or Header  |  1996-06-04  |  11KB  |  462 lines

  1. /* $Id: ljiip.c,v 1.7 1995/03/11 20:27:10 mjl Exp $
  2.  * $Log: ljiip.c,v $
  3.  * Revision 1.7  1995/03/11  20:27:10  mjl
  4.  * All drivers: eliminated unnecessary variable initializations, other cleaning
  5.  * up.
  6.  *
  7.  * Revision 1.6  1995/01/06  07:40:32  mjl
  8.  * All drivers: pls->width now more sensibly handled.  If the driver supports
  9.  * multiple widths, it first checks to see if it has been initialized
  10.  * already (e.g. from the command line) before initializing it.  For drivers
  11.  * that don't support multiple widths, pls->width is ignored.
  12.  *
  13.  * Revision 1.5  1995/01/04  04:43:20  mjl
  14.  * Minor tweek.  Modified the pixel width to depend on the slope of the line.
  15.  * Makes diagonal lines thinner.  Contributed by Wesley Ebisuzaki.
  16. */
  17.  
  18. /*    ljiip.c
  19.  
  20.     PLplot Laser Jet IIp device driver.
  21.     Based on old LJII driver, modifications by Wesley Ebisuzaki
  22.  
  23.     DPI = 300, 150, 100    (dots per inch)
  24.         default: Amiga/Unix 300 dpi, MS-DOS 150 dpi
  25.         higher = better output, more memory, longer to print
  26.     GCMODE = 0, 2 (graphics compression mode)
  27.         default: 2,  old laser jets should use 0
  28.         compression can speed up the printing up to 3x
  29.  
  30. */
  31. #include "plDevs.h"
  32.  
  33. #ifdef PLD_ljii
  34.  
  35. #include "plplotP.h"
  36. #include "drivers.h"
  37. #include <math.h>
  38. #include <string.h>
  39.  
  40. #ifdef __GO32__            /* dos386/djgpp */
  41. #ifdef MSDOS
  42. #undef MSDOS
  43. #endif
  44. #endif
  45.  
  46. /* Function prototypes */
  47.  
  48. static void setpoint(PLINT, PLINT);
  49.  
  50. /* top level declarations */
  51.  
  52. /* GCMODE = graphics compression mode, 0=old laser jets, 2=ljiip or later */
  53. #define GCMODE   2
  54.  
  55. /* DPI = dots per inch, more dots=better plot, more memory, more time */
  56. /* possible DPI = 75, 100, 150, 300 */
  57. /* if DPI=300 then your machine must have a free 1Mb block of memory */
  58.  
  59. #define DPI      300
  60.  
  61. #ifdef MSDOS
  62. #undef  DPI
  63. #define DPI      150
  64. #endif
  65.  
  66. #define OF    pls->OutFile
  67. #define CURX    ((long) (DPI / 5))
  68. #define CURY    ((long) (DPI / 7))
  69. #define XDOTS    (376 * (DPI / 50))    /* # dots across */
  70. #define YDOTS    (500 * (DPI / 50))    /* # dots down */
  71. #define JETX    (XDOTS-1)
  72. #define JETY    (YDOTS-1)
  73.  
  74.  
  75. #define BPROW    (XDOTS/8L)        /* # bytes across */
  76. #define MAX_WID    8            /* max pen width in pixels */
  77. #define BPROW1    (BPROW + (MAX_WID+7)/8)    /* pen has width, make bitmap bigger */
  78. #define NBYTES    BPROW1*(YDOTS+MAX_WID)    /* total number of bytes */
  79.  
  80. /* Graphics control characters. */
  81.  
  82. #define ESC      0x1b
  83. #define FF       0x0c
  84.  
  85. static char mask[8] =
  86. {'\200', '\100', '\040', '\020', '\010', '\004', '\002', '\001'};
  87.  
  88. #ifndef MSDOS
  89. #define _HUGE
  90. #else
  91. #define _HUGE _huge
  92. #endif
  93.  
  94. static unsigned char _HUGE *bitmap;    /* memory area NBYTES in size */
  95.  
  96. /*--------------------------------------------------------------------------*\
  97.  * plD_init_ljiip()
  98.  *
  99.  * Initialize device.
  100. \*--------------------------------------------------------------------------*/
  101.  
  102. void
  103. plD_init_ljiip(PLStream *pls)
  104. {
  105.     PLDev *dev;
  106.  
  107.     if (pls->width == 0)    /* Is 0 if uninitialized */
  108.     pls->width = DPI / 100;
  109.  
  110. /* Initialize family file info */
  111.  
  112.     plFamInit(pls);
  113.  
  114. /* Prompt for a file name if not already set */
  115.  
  116.     plOpenFile(pls);
  117.  
  118. /* Allocate and initialize device-specific data */
  119.  
  120.     dev = plAllocDev(pls);
  121.  
  122.     dev->xold = UNDEFINED;
  123.     dev->yold = UNDEFINED;
  124.     dev->xmin = 0;
  125.     dev->ymin = 0;
  126.  
  127. /* number of pixels / mm */
  128.  
  129.     plP_setpxl((PLFLT) (DPI/25.4), (PLFLT) (DPI/25.4));
  130.  
  131. /* Rotate by 90 degrees since portrait mode addressing is used */
  132.  
  133.     dev->xmin = 0;
  134.     dev->ymin = 0;
  135.     dev->xmax = JETX; /*Change here */
  136.     dev->ymax = JETY;
  137.    
  138.     dev->xlen = dev->xmax - dev->xmin;
  139.     dev->ylen = dev->ymax - dev->ymin;
  140.  
  141.     plP_setphy(dev->xmin, dev->xmax, dev->ymin, dev->ymax);
  142.  
  143. /* Allocate storage for bit map matrix */
  144.  
  145. #ifdef MSDOS
  146.     if ((bitmap = (unsigned char _HUGE *)
  147.      halloc((long) NBYTES, sizeof(char))) == NULL)
  148.     plexit("Out of memory in call to calloc");
  149. #else
  150.     if ((bitmap = (unsigned char *) calloc(NBYTES, sizeof(char))) == NULL)
  151.     plexit("Out of memory in call to calloc");
  152. #endif
  153.  
  154. /* Reset Printer */
  155.  
  156.     fprintf(OF, "%cE", ESC);
  157. }
  158.  
  159. /*--------------------------------------------------------------------------*\
  160.  * plD_line_ljiip()
  161.  *
  162.  * Draw a line in the current color from (x1,y1) to (x2,y2).
  163. \*--------------------------------------------------------------------------*/
  164.  
  165. void
  166. plD_line_ljiip(PLStream *pls, short x1a, short y1a, short x2a, short y2a)
  167. {
  168.     PLDev *dev = (PLDev *) pls->dev;
  169.     int x1 = x1a, y1 = y1a, x2 = x2a, y2 = y2a;
  170.     int abs_dx, abs_dy, dx, dy, incx, incy;
  171.     int i, j, width, residual;
  172.     PLFLT tmp;
  173.  
  174.     width = MIN(plsc->width, MAX_WID); /*Change here */
  175.  
  176. /* Take mirror image, since PCL expects (0,0) to be at top left */
  177.  
  178.     y1 = dev->ymax - (y1 - dev->ymin);
  179.     y2 = dev->ymax - (y2 - dev->ymin);
  180.  
  181. /*Change here 
  182.     { plRotPhy(1, dev->xmin, dev->ymin, dev->xmax, dev->ymax, &x1, &y1);
  183.       plRotPhy(1, dev->xmin, dev->ymin, dev->xmax, dev->ymax, &x2, &y2);
  184.     }*/
  185.  
  186.     dx = x2 - x1;
  187.     dy = y2 - y1;
  188.  
  189.     if (dx < 0) {
  190.     abs_dx = -dx;
  191.     incx = -1;
  192.     }
  193.     else {
  194.     abs_dx = dx;
  195.     incx = 1;
  196.     }
  197.     if (dy < 0) {
  198.     abs_dy = -dy;
  199.     incy = -1;
  200.     }
  201.     else {
  202.     abs_dy = dy;
  203.     incy = 1;
  204.     }
  205.  
  206. /* make pixel width narrower for diag lines */
  207.  
  208.     if (abs_dy <= abs_dx) {
  209.     if (abs_dx == 0)
  210.         tmp = 1.0;
  211.     else
  212.         tmp = 1.0 - (PLFLT) abs_dy / abs_dx;
  213.     }
  214.     else {
  215.     tmp = 1.0 - (PLFLT) abs_dx / abs_dy;
  216.     }
  217.  
  218.     width = floor(0.5 + width * (tmp*tmp*tmp*(1.0-0.707107) + 0.707107));
  219.  
  220.     if (width < 1) width = 1;
  221.     if (width > 1) {
  222.     for (i = 0; i < width; i++) {
  223.         for (j = 0; j < width; j++) {
  224.             setpoint((PLINT) (x1+i), (PLINT) (y1+j));
  225.             setpoint((PLINT) (x2+i), (PLINT) (y2+j));
  226.         }
  227.     }
  228.     }
  229.     if (abs_dx >= abs_dy) {
  230.     residual = -(abs_dx >> 1);
  231.     if (width == 1) {
  232.             for (i = 0; i <= abs_dx; i++, x1 += incx) {
  233.                 setpoint((PLINT) (x1), (PLINT) (y1));
  234.                 if ((residual += abs_dy) >= 0) {
  235.                     residual -= abs_dx;
  236.                     y1 += incy;
  237.                 }
  238.             }
  239.     }
  240.     else {
  241.         for (i = 0; i <= abs_dx; i++, x1 += incx) {
  242.            for (j = 0; j < width; j++) {
  243.                setpoint((PLINT) (x1), (PLINT) (y1+j));
  244.                setpoint((PLINT) (x1+width-1), (PLINT) (y1+j));
  245.            }
  246.            if ((residual += abs_dy) >= 0) {
  247.            residual -= abs_dx;
  248.            y1 += incy;
  249.            }
  250.         }
  251.     }
  252.     }
  253.     else {
  254.     residual = -(abs_dy >> 1);
  255.         if (width == 1) {
  256.             for (i = 0; i <= abs_dy; i++, y1 += incy) {
  257.                 setpoint((PLINT) (x1), (PLINT) (y1));
  258.                 if ((residual += abs_dx) >= 0) {
  259.                     residual -= abs_dy;
  260.                     x1 += incx;
  261.                 }
  262.             }
  263.         }
  264.         else {
  265.             for (i = 0; i <= abs_dy; i++, y1 += incy) {
  266.                for (j = 0; j < width; j++) {
  267.                    setpoint((PLINT) (x1+j), (PLINT) (y1));
  268.                    setpoint((PLINT) (x1+j), (PLINT) (y1+width-1));
  269.                }
  270.                if ((residual += abs_dx) >= 0) {
  271.                    residual -= abs_dy;
  272.                    x1 += incx;
  273.                }
  274.             }
  275.         }
  276.     }
  277. }
  278.  
  279. /*--------------------------------------------------------------------------*\
  280.  * plD_polyline_ljiip()
  281.  *
  282.  * Draw a polyline in the current color.
  283. \*--------------------------------------------------------------------------*/
  284.  
  285. void
  286. plD_polyline_ljiip(PLStream *pls, short *xa, short *ya, PLINT npts)
  287. {
  288.     PLINT i;
  289.  
  290.     for (i = 0; i < npts - 1; i++)
  291.     plD_line_ljiip(pls, xa[i], ya[i], xa[i + 1], ya[i + 1]);
  292. }
  293.  
  294. /*--------------------------------------------------------------------------*\
  295.  * plD_eop_ljiip()
  296.  *
  297.  * End of page.(prints it here).
  298. \*--------------------------------------------------------------------------*/
  299.  
  300. void
  301. plD_eop_ljiip(PLStream *pls)
  302. {
  303.     PLINT j;
  304.     unsigned char _HUGE *p;
  305. #if GCMODE > 0
  306.     int i, iy, last, n, jmax;
  307.     unsigned char _HUGE t_buf[BPROW*2];
  308.     unsigned char c;
  309. #endif
  310.  
  311. /* PCL III setup: ref. Deskjet Plus Printer Owner's Manual */
  312.  
  313.     fprintf(OF,"\033*rB");          /* end raster graphics */
  314.     fprintf(OF,"\033*t%3dR", DPI);    /* set DPI */
  315.  
  316. #if GCMODE != 0
  317.     fprintf(OF,"\033*r%dS", XDOTS);    /* raster width */
  318.     fprintf(OF,"\033*b%1dM", GCMODE);    /* graphics mode */
  319. #endif
  320.  
  321. /* First move cursor to origin */
  322.  
  323.     fprintf(OF,"\033*p%ldX", CURX);
  324.     fprintf(OF,"\033*p%ldY", CURY);
  325.     fprintf(OF,"\033*r0A");        /* start graphics */
  326.  
  327. /* Write out raster data */
  328.  
  329. #if GCMODE == 0
  330.     for (j = 0, p = bitmap; j < YDOTS; j++, p += BPROW1) {
  331.     fprintf(OF,"\033*b>%dW", BPROW);
  332.     fwrite(p, BPROW, sizeof(char), OF);
  333.     }
  334. #endif
  335. #if GCMODE == 2
  336.     for (iy = 0, p = bitmap; iy < YDOTS; iy++, p += BPROW1) {
  337.  
  338.     /* find last non-zero byte */
  339.  
  340.     last = BPROW - 1;
  341.     while (last > 0 && p[last] == 0) last--;
  342.     last++;
  343.  
  344.     /* translate to mode 2, save results in t_buf[] */
  345.  
  346.     i = n = 0;
  347.     while (i < last) {
  348.         c = p[i];
  349.         jmax = i + 127;
  350.         jmax = last < jmax ? last : jmax;
  351.         if (i < last - 2 && (c == p[i+1]) && (c == p[i+2])) {
  352.         j = i + 3;
  353.         while (j < jmax && c == p[j]) j++;
  354.         t_buf[n++] = (i-j+1) & 0xff;
  355.         t_buf[n++] = c;
  356.         i = j;
  357.         }
  358.         else {
  359.         for (j = i + 1; j < jmax; j++) {
  360.             if (j < last - 2 && (p[j] == p[j+1]) &&
  361.             (p[j+1] == p[j+2]) ) break;
  362.         }
  363.         t_buf[n++] = j - i - 1;
  364.         while (i < j) {
  365.             t_buf[n++] = p[i++];
  366.         }
  367.         }
  368.     }
  369.     fprintf(OF,"\033*b%dW", (int) n);
  370.     fwrite(t_buf, (int) n, sizeof(char), OF);
  371.     }
  372. #endif
  373.  
  374.     pls->bytecnt += NBYTES;
  375.  
  376. /* End raster graphics and send Form Feed */
  377.  
  378.     fprintf(OF, "\033*rB");
  379.     fprintf(OF, "%c", FF);
  380.  
  381. /* Finally, clear out bitmap storage area */
  382.  
  383.     memset((void *) bitmap, '\0', NBYTES);
  384. }
  385.  
  386. /*--------------------------------------------------------------------------*\
  387.  * plD_bop_ljiip()
  388.  *
  389.  * Set up for the next page.
  390.  * Advance to next family file if necessary (file output).
  391. \*--------------------------------------------------------------------------*/
  392.  
  393. void
  394. plD_bop_ljiip(PLStream *pls)
  395. {
  396.     if (!pls->termin)
  397.     plGetFam(pls);
  398.  
  399.     pls->page++;
  400. }
  401.  
  402. /*--------------------------------------------------------------------------*\
  403.  * plD_tidy_ljiip()
  404.  *
  405.  * Close graphics file or otherwise clean up.
  406. \*--------------------------------------------------------------------------*/
  407.  
  408. void
  409. plD_tidy_ljiip(PLStream *pls)
  410. {
  411. /* Reset Printer */
  412.  
  413.     fprintf(OF, "%cE", ESC);
  414.     fclose(OF);
  415.     free((char *) bitmap);
  416. }
  417.  
  418. /*--------------------------------------------------------------------------*\
  419.  * plD_state_ljiip()
  420.  *
  421.  * Handle change in PLStream state (color, pen width, fill attribute, etc).
  422. \*--------------------------------------------------------------------------*/
  423.  
  424. void 
  425. plD_state_ljiip(PLStream *pls, PLINT op)
  426. {
  427. }
  428.  
  429. /*--------------------------------------------------------------------------*\
  430.  * plD_esc_ljiip()
  431.  *
  432.  * Escape function.
  433. \*--------------------------------------------------------------------------*/
  434.  
  435. void
  436. plD_esc_ljiip(PLStream *pls, PLINT op, void *ptr)
  437. {
  438. }
  439.  
  440. /*--------------------------------------------------------------------------*\
  441.  * setpoint()
  442.  *
  443.  * Sets a bit in the bitmap.
  444. \*--------------------------------------------------------------------------*/
  445.  
  446. static void
  447. setpoint(PLINT x, PLINT y)
  448. {
  449.     PLINT index;
  450.     index = x / 8 + y * BPROW1;
  451.     *(bitmap + index) = *(bitmap + index) | mask[x % 8];
  452. }
  453.  
  454. #else
  455. int 
  456. pldummy_ljiip()
  457. {
  458.     return 0;
  459. }
  460.  
  461. #endif                /* PLD_ljii */
  462.